﻿using AnesSystem.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Printing;
using System.Windows.Markup;
using System.IO;
using System.Xml;
using System.Windows.Documents;
using AnesSystem.Controls;

namespace AnesSystem
{
    public abstract class PrintTemplate : UserControl
    {

        #region Variables

        //原缩放比例
        protected ScaleTransform _oScaleTransform;

        //旋转
        protected RotateTransform _oRotateTransform;

        //渲染组
        protected TransformGroup _oTransformGroup;

        //界面缩放
        protected ScaleTransform _viewScaleTransform;



        //默认比例
        protected double defaultScale = 0.64;

        protected PrintDialog p = null;

        #endregion

        #region Constructor

        public PrintTemplate()
        {
            //_oTransformGroup = new TransformGroup();

            _oScaleTransform = new ScaleTransform();
            _oScaleTransform.ScaleX = 1;
            _oScaleTransform.ScaleY = 1;

            //_oTransformGroup.Children.Add(_oScaleTransform);

            //_oRotateTransform = new RotateTransform(0);
            //_oTransformGroup.Children.Add(_oRotateTransform);

            _viewScaleTransform = new ScaleTransform();
            _viewScaleTransform.ScaleX = 1;
            _viewScaleTransform.ScaleY = 1;

            p = new PrintDialog();
            p.UserPageRangeEnabled = true;

            //Width = 1190;
            PageOrientation = System.Printing.PageOrientation.ReverseLandscape;
        }

        #endregion

        #region Properties

        /// <summary>
        /// 打印方向
        /// </summary>
        public System.Printing.PageOrientation PageOrientation
        {
            get; set;
        }

        public static PrintTemplate PrintVisul { get; set; }

        #endregion

        #region 依赖属性

        #endregion

        #region Event

        #endregion

        #region Private Methods

        private void PrintAll(FrameworkElement visual)
        {
            try
            {
                InvokePrePrint();
                p.PrintTicket.PageOrientation = PageOrientation;
                if (!p.PrintQueue.FullName.Contains("Microsoft XPS Document Writer") && !p.PrintQueue.FullName.Contains("Microsoft Print to PDF"))
                {
                    var size = new System.Windows.Size(visual.ActualWidth, visual.ActualHeight);
                    visual.Measure(size);
                    visual.Arrange(new System.Windows.Rect(size));
                    visual.RenderTransform = GetScale(visual);
                    visual.UpdateLayout();
                    bool isEnable = visual.IsEnabled;
                    visual.IsEnabled = true;
                    p.PrintVisual(visual, "");
                    visual.IsEnabled = isEnable;
                    visual.RenderTransform = _oRotateTransform;
                }
                else
                {
                    p.PrintVisual(visual, "");
                }
            }
            catch (Exception ex)
            {
                Common.LogHelper.Error(this.GetType(), ex);
            }
            finally
            {
                InvokeOverPrint();
            }
        }

        /// <summary>
        /// 单面打印
        /// </summary>
        /// <param name="visualList"></param>
        private void SinglePagePrint(List<FrameworkElement> visualList)
        {
            if (visualList.Count <= 0) return;
            foreach (var item in visualList)
            {
                PrintAll(item);
            }
        }

        /// <summary>
        /// 双面打印
        /// </summary>
        /// <param name="visualList"></param>
        private void DoublePagePrint(List<FrameworkElement> visualList)
        {
            if (visualList.Count <= 0) return;
            Size printtSize = new Size(p.PrintableAreaWidth, p.PrintableAreaHeight);
            Size singeSize = new Size(visualList.FirstOrDefault().ActualWidth, visualList.FirstOrDefault().ActualHeight);
            ScaleTransform s = GetScale(visualList.FirstOrDefault());
            CustomDocumentPaginator c = new CustomDocumentPaginator(visualList, printtSize, singeSize, visualList.Count, s);
            if (!p.PrintQueue.FullName.Contains("Microsoft XPS Document Writer") && !p.PrintQueue.FullName.Contains("Microsoft Print to PDF"))
            {
                p.PrintDocument(c, "");
                foreach (var item in visualList)
                {
                    item.RenderTransform = _oScaleTransform;
                }
            }
            else
            {
                foreach (var item in visualList)
                {
                    PrintAll(item);
                }
            }
        }

        #endregion

        #region Public/Protected Methods

        public void HyScale()
        {
            this.LayoutTransform = _oRotateTransform;
        }


        public virtual ScaleTransform GetScale()
        {
            ScaleTransform scaleTransform = new ScaleTransform();
            scaleTransform.ScaleY = p.PrintableAreaHeight / ActualHeight;
            scaleTransform.ScaleX = p.PrintableAreaWidth / ActualWidth;
            return scaleTransform;
        }
        public virtual ScaleTransform GetScale(FrameworkElement visual)
        {
            ScaleTransform scaleTransform = new ScaleTransform();
            scaleTransform.ScaleY = Math.Round(p.PrintableAreaHeight / visual.ActualHeight, 2);
            scaleTransform.ScaleX = Math.Round(p.PrintableAreaWidth / visual.ActualWidth, 2);
            return scaleTransform;
        }

        /// <summary>
        /// 带弹框打印本身
        /// </summary>
        public void Print()
        {
            if ((bool)p.ShowDialog())
            {
                PrintVisual();
            }
        }

        /// <summary>
        /// 不带弹框打印集合
        /// </summary>
        /// <param name="visualList">打印控件集合</param>
        /// <param name="isDoublePaging">是否双面打印，默认双面</param>
        public void Print(List<FrameworkElement> visualList, bool isDoublePaging = true)
        {
            InvokePrePrint();
            try
            {
                p.PrintTicket.PageOrientation = PageOrientation;
                List<FrameworkElement> list = new List<FrameworkElement>();
                if (p.PageRangeSelection == PageRangeSelection.UserPages)
                {
                    if(p.PageRange.PageTo <= visualList.Count)
                    {
                        if (p.PageRange.PageFrom == p.PageRange.PageTo)
                        {
                            list = visualList.GetRange(p.PageRange.PageFrom-1, 1);
                        }
                        else
                        {
                            list = visualList.GetRange(p.PageRange.PageFrom - 1, p.PageRange.PageTo - p.PageRange.PageFrom);
                        }
                    }
                }
                else
                {
                    list = visualList;
                }
                if (!isDoublePaging)
                {
                    SinglePagePrint(list);
                }
                else
                {
                    DoublePagePrint(list);
                }
                
            }
            catch (Exception ex)
            {
                Common.LogHelper.Error(this.GetType(), ex);
            }
            finally
            {
                InvokeOverPrint();
            }

        }

        

        /// <summary>
        /// 打印前调用
        /// </summary>
        public abstract void InvokePrePrint();

        /// <summary>
        /// 打印完毕后调用
        /// </summary>
        public abstract void InvokeOverPrint();

        /// <summary>
        /// 不带弹框打印
        /// </summary>
        /// <param name="visual"></param>
        public void Print(FrameworkElement visual)
        {
            PrintAll(visual);
        }

        /// <summary>
        /// 不带弹框打印本身,可被重写，调用其它打印
        /// </summary>
        public virtual void PrintVisual()
        {
            PrintAll(this);
        }

        public virtual void ScaleView(bool isZoomIn)
        {
            if (isZoomIn)
            {
                _viewScaleTransform.ScaleX += 0.1;
                _viewScaleTransform.ScaleY += 0.1;
            }
            else
            {
                if ((float)_viewScaleTransform.ScaleX == (float)0.3) return;
                _viewScaleTransform.ScaleX -= 0.1;
                _viewScaleTransform.ScaleY -= 0.1;
            }
            SysMainBottomCtrlViewModel.Instance.ScaleDouble = _viewScaleTransform.ScaleX;
            SysMainBottomCtrlViewModel.Instance.Scale = _viewScaleTransform.ScaleX * 100 + "%";
            this.LayoutTransform = _viewScaleTransform;
        }

        #endregion

        #region EventHandlers

        #endregion
    }
}